// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.credentialStore.com.intellij.credentialStore.keePass

import com.intellij.credentialStore.EncryptionSpec
import com.intellij.credentialStore.EncryptionType
import com.intellij.credentialStore.getDefaultEncryptionType
import com.intellij.credentialStore.keePass.BaseKeePassFileManagerTest
import com.intellij.credentialStore.keePass.MASTER_KEY_FILE_NAME
import com.intellij.credentialStore.keePass.MasterKeyFileStorage
import com.intellij.credentialStore.keePass.TestKeePassFileManager
import com.intellij.testFramework.UsefulTestCase
import com.intellij.testFramework.assertions.Assertions.assertThat
import com.intellij.util.io.delete
import com.intellij.util.io.readText
import org.junit.Assume
import org.junit.Test

internal class KeePassSetMasterPasswordTest : BaseKeePassFileManagerTest() {
  @Test
  fun `new database`() {
    TestKeePassFileManager(createStore(), masterPasswordRequestAnswer = "boo")
      .askAndSetMasterKey(event = null)

    val store = createStore()
    assertThat(store.dbFile).exists()
    assertThat(store.masterKeyFile.readText()).startsWith("""
       encryption: ${getDefaultEncryptionType().name}
       isAutoGenerated: false
       value: !!binary
     """.trimIndent())
    assertThat(MasterKeyFileStorage(store.masterKeyFile).load()!!.toString(Charsets.UTF_8)).isEqualTo("boo")
  }

  @Test
  fun `protect using PGP - new database`() {
    Assume.assumeTrue("not for Teamcity", !UsefulTestCase.IS_UNDER_TEAMCITY)

    TestKeePassFileManager(createStore(), masterPasswordRequestAnswer = "boo", masterKeyEncryptionSpec = EncryptionSpec(EncryptionType.PGP_KEY, "A769DF87"))
      .askAndSetMasterKey(event = null)

    val store = createStore()
    assertThat(store.dbFile).exists()
    assertThat(store.masterKeyFile.readText()).startsWith("""
       encryption: PGP_KEY
       isAutoGenerated: false
       value: !!binary
     """.trimIndent())
    assertThat(MasterKeyFileStorage(store.masterKeyFile).load()!!.toString(Charsets.UTF_8)).isEqualTo("boo")

    TestKeePassFileManager(createStore(), masterPasswordRequestAnswer = "boo", masterKeyEncryptionSpec = EncryptionSpec(EncryptionType.BUILT_IN, pgpKeyId = null))
      .saveMasterKeyToApplyNewEncryptionSpec()

    assertThat(store.masterKeyFile.readText()).startsWith("""
       encryption: BUILT_IN
       isAutoGenerated: false
       value: !!binary
     """.trimIndent())
  }

  @Test
  fun `existing database with the same master password but incorrect master key file`() {
    TestKeePassFileManager(createTestStoreWithCustomMasterKey(), masterPasswordRequestAnswer = "foo")
      .askAndSetMasterKey(event = null)

    val store = createStore()
    assertThat(store.dbFile).exists()
    assertThat(MasterKeyFileStorage(store.masterKeyFile).load()!!.toString(Charsets.UTF_8)).isEqualTo("foo")
  }

  @Test
  fun `existing database with the different master password and incorrect master key file`() {
    val existingStore = createTestStoreWithCustomMasterKey()
    fsRule.fs.getPath("/$MASTER_KEY_FILE_NAME").delete()
    TestKeePassFileManager(existingStore, oldMasterPasswordRequestAnswer = "foo", masterPasswordRequestAnswer = "new")
      .askAndSetMasterKey(event = null)

    val store = createStore()
    assertThat(store.dbFile).exists()
    assertThat(store.masterKeyFile).exists()
  }
}